#ifndef CAMERA_HPP
#define CAMERA_HPP

#include "Objects/Object3D.hpp"

#include <iostream>
#include <GLFW/glfw3.h>
#include <glm/vec3.hpp>
#include <glm/mat4x4.hpp>
#include <glm/gtc/matrix_transform.hpp>


const float ONE_DEG_IN_RAD = 3.1415926535f / 180.0f;
template<typename T> inline const T R(T degrees) { return degrees * ONE_DEG_IN_RAD; } // 3.1415926535


class Camera : public Object3D
{
public:
	float speed, sens;
	GLFWwindow* window;
	glm::mat4 proj_matrix;

	Camera(GLFWwindow* window, const flecs::world& ecs, const vec3& position, const glm::vec3& direction, float speed, float fov, float sensity);
	void rotate_callback(float x, float y);
	void process(float delta_);

	void lookAt(const vec3& position);
	inline const glm::vec3 getDirection() const
	{
		return direction;
	}
	inline void setDirection(const glm::vec3& direction)
	{
		lookAt(direction);
	}

private:
	float lastx, lasty;
	bool cursor_actived = true;
	bool firstCursorAppear = true;

	float pitch = 0.f;
	float yaw   = glm::radians(-90.0f);

	glm::vec3 start_direction, direction;
	const glm::vec3 globalUp = glm::vec3(0.f, 1.f, 0.f);

	inline void setDirection()
	{
		getEntity().set<quat, tagRotation>(glm::quat(glm::normalize(direction), globalUp));
	}
	void move(const glm::vec3& move)
	{
		getEntity().set<vec3, tagPosition>(getPosition() + move);
	}
};
#endif // CAMERA_HPP
